/*
 * @version: 1.0
 * @Author: zhl
 * @Date: 2021-09-16 10:11:25
 * @LastEditors: zhl
 * @LastEditTime: 2022-01-27 17:11:30
 * @Description: 任务线程，主要用于定时把任务发送到接口线程。
 */

#include "TaskThreadManager.h"
#include "CLogger.h"
#include "common.h"
#include "app.h"



TaskThreadManager::TaskThreadManager(std::shared_ptr<CConfigManager> cm, std::unordered_map<std::string, std::shared_ptr<HandleThreadManager>> &htm){
    c_is_run = true;
    c_cm = cm;
    c_task_params = std::make_shared<std::unordered_map<int64_t, TASK_PARAMS>>();
    if(!htm.empty()){
        c_htms.insert(htm.begin(), htm.end());
    }
}

TaskThreadManager::~TaskThreadManager(){
}

void *TaskThreadManager::handle_thread(void *arg){
    pthread_detach(pthread_self());
    if(NULL == arg){
        return NULL;
    }
    TaskThreadManager *ttm = (TaskThreadManager *)arg;
    if(ttm->c_task_params->empty()){
        return NULL;
    }
    ttm->c_is_run = true;
    uint32_t v_intervaltime = ttm->get_intervaltime(ttm->c_task_params->begin()->second.task_id, true);
    //第一次执行需要等待的时间
    millisecond_sleep(v_intervaltime);
    v_intervaltime = ttm->get_intervaltime(ttm->c_task_params->begin()->second.task_id);
    while(ttm->c_is_run){
        //此处调用协议模块处理任务信息。
        for(auto dev = ttm->c_task_params->begin(); dev != ttm->c_task_params->end(); dev++){
            auto v_dev = ttm->c_cm->get_terminal_device(dev->second.dev_id);
            if(nullptr == v_dev){
                CLogger::getInstance()->LOG_W("该设备不存在");
                continue;
            }
            auto v_if = ttm->c_htms.find(v_dev->channel);
            if(v_if == ttm->c_htms.end()){
                CLogger::getInstance()->LOG_W("通信接口不存在");
                continue;
            }
            v_if->second->add_task_items(dev->second);
        }
        //此处需要处理时间间隔
        millisecond_sleep(v_intervaltime);
    }
    return NULL;
}

int TaskThreadManager::execute(std::unordered_map<int64_t, TASK_PARAMS> &devs){

    if(devs.empty()){
        CLogger::getInstance()->LOG_W("该任务没有任务项");
        return -1;
    }

    c_task_params->insert(devs.begin(), devs.end());

    return pthread_create(&c_thread, NULL, handle_thread, this);
}

int TaskThreadManager::wait_thread_finish(){
    return pthread_cancel(c_thread);
}

void TaskThreadManager::stop(){
    c_is_run = false;
    // for(auto htm = c_htms.begin(); htm != c_htms.end(); htm++){
    //     htm->second->stop();
    // }
    wait_thread_finish();
}

uint32_t  TaskThreadManager::get_intervaltime(int64_t task_id, bool is_first){
    std::shared_ptr<TASK> task = c_cm->get_task(task_id);
    uint32_t v_intervaltime = 900000;  //默认15分钟
    if((nullptr == task) || (1 > task->interval_time)){
        v_intervaltime = 900000;   //默认15分钟
    }else{
        v_intervaltime = task->interval_time*1000;
    }
    //
    if(true == is_first){
        int v_it = 0;
        uint64_t start_time = get_timestamp_by_time_string(task->start_time)*1000;
        v_it = start_time - get_timestamp();
        if(0 < v_it){
            v_intervaltime = v_it % v_intervaltime;
        } else {
            v_intervaltime = v_intervaltime - (abs(v_it) % v_intervaltime);
        }        
    }
    return v_intervaltime;
}